#include "FirstPersonCamera.h"

using namespace Graphics;

FirstPersonCamera::FirstPersonCamera() :
  viewdirchanged(false),
  position(0,0,0),
  viewdir(0,0,1),
  rotatedX(0),
  rotatedY(0),
  rotatedZ(0)
{
  GetViewDir();
}

FirstPersonCamera::FirstPersonCamera(double x, double y, double z) :
  viewdirchanged(true),
  position(x, y, z),
  viewdir(0, 0, 1),
  rotatedX(0),
  rotatedY(0),
  rotatedZ(0)
{
  GetViewDir();
}

FirstPersonCamera::FirstPersonCamera(const FirstPersonCamera &other)
{
  viewdirchanged = other.viewdirchanged;
  position = other.position;
  viewdir = other.viewdir;
  rotatedX = other.rotatedX;
  rotatedY = other.rotatedY;
  rotatedZ = other.rotatedZ;
}

FirstPersonCamera::~FirstPersonCamera()
{

}

FirstPersonCamera& FirstPersonCamera::operator=(const FirstPersonCamera &rhs)
{
  if(&rhs==this)
    return *this;

  viewdirchanged = rhs.viewdirchanged;
  position = rhs.position;
  viewdir = rhs.viewdir;
  rotatedX = rhs.rotatedX;
  rotatedY = rhs.rotatedY;
  rotatedZ = rhs.rotatedZ;

  return *this;
}


void FirstPersonCamera::GetViewDir()
{
  vmml::Vector3d Step1, Step2;
  //Rotate around Y-axis:
  Step1.x = cos((rotatedY + 90.0) * PIdiv180);
  Step1.z = -sin((rotatedY + 90.0) * PIdiv180);
  //Rotate around X-axis:
  double cosX = cos(rotatedX * PIdiv180);
  Step2.x = Step1.x * cosX;
  Step2.z = Step1.z * cosX;
  Step2.y = sin(rotatedX * PIdiv180);
  //Rotation around Z-axis not yet implemented, so:
  viewdir = Step2;
}


void FirstPersonCamera::Move(const vmml::Vector3d Direction)
{
  position+=Direction;
}


void FirstPersonCamera::RotateY(double Angle)
{
  rotatedY += Angle;
  viewdirchanged = true;
}

void FirstPersonCamera::RotateX(double Angle)
{
  rotatedX += Angle;
  viewdirchanged = true;
}


void FirstPersonCamera::MoveForwards(double Distance)
{
  if(viewdirchanged)
    GetViewDir();
  vmml::Vector3d MoveVector;
  MoveVector.x = viewdir.x * -Distance;
  MoveVector.y = viewdir.y * -Distance;
  MoveVector.z = viewdir.z * -Distance;
  position+=MoveVector;
}

void FirstPersonCamera::StrafeRight(double Distance)
{
  if(viewdirchanged)
    GetViewDir();
  vmml::Vector3d MoveVector;
  MoveVector.z = -viewdir.x * -Distance;
  MoveVector.y = 0.0;
  MoveVector.x = viewdir.z * -Distance;
  position+=MoveVector;
}

void FirstPersonCamera::setModelView() const
{
  glLoadIdentity();
  glRotated(-rotatedX , 1.0, 0.0, 0.0);
  glRotated(-rotatedY , 0.0, 1.0, 0.0);
  glRotated(-rotatedZ , 0.0, 0.0, 1.0);
  glTranslated( -position.x, -position.y, -position.z );
}
